import asyncio
import json
import random
from typing import Annotated

import uvicorn
from fastapi import FastAPI, Cookie, Query
from starlette.websockets import WebSocket

from conn_manager import ConnectionManager
from req import WsMsg
from service.schedule import ScheduleService

app = FastAPI()
scheduleService = ScheduleService()


@app.get("/")
async def root():
    return {"message": "Hello World"}


@app.get("/hello/{name}")
async def say_hello(name: str):
    return {"message": f"Hello {name}"}


#
# @app.post("/schedule/0")
# async def schedule_reg_device(req: RegDevice):
#     """注册设备"""
#     print(req)
#     return {
#         "code": 0,
#         "msg": "OK"
#     }


# @app.post("/schedule/7")
# async def schedule_bag_reg(req: LiveRoom):
#     """提交福袋直播间信息"""
#     return scheduleService.save_live_room(req)


manager = ConnectionManager()


async def get_cookie_or_token(
        websocket: WebSocket,
        session: Annotated[str | None, Cookie()] = None,
        token: Annotated[str | None, Query()] = None,
):
    print(f"get_cookie_or_token={token}")
    # if session is None and token is None:
    #     raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)
    # return session or token
    return "no-token"


async def mock_send_msg(websocket):
    """fixme 模拟发送消息，切换脚本"""
    while True:
        # print("start loop")
        ips = ["192.168.0.151", "192.168.0.152"]
        script = ["KwSearchBagScript", "KwWaitOpenScript", "KwGoldOutScript"]
        payloads = [{"KwSearchBagScript": "booo"}, {"scheme_url": "kwai://live/play/[LiveStreamId]/"},
                    {"room_id": "12123123123", "room_link": "http:kwkuai.com/XXXXX"}]
        randint = random.randint(0, len(script) - 1)

        msg = WsMsg("switch", "", "", [
            {
                "ip": ips[0],
                "script": script[randint],
                "payload": payloads[randint]

            }, {
                "ip": ips[1],
                "script": script[randint],
                "payload": payloads[randint]
            }
        ]
                    )
        # dumps = json.dumps(data)
        await websocket.send_json(json.dumps(msg.__dict__))
        print("send...data")
        await asyncio.sleep(30)


async def recv(websocket):
    while True:
        message = await websocket.receive_text()
        print(f"接受来自客户端的消息={message}")
        message = json.loads(message)
        from_msg = WsMsg(message.get('cmd'), message.get('req_id'), message.get('token'), message.get('data'))
        to_msg = scheduleService.dispatch(from_msg)
        print(f"返回给客户端的消息={to_msg.__dict__}")
        try:
            await websocket.send_text(json.dumps(to_msg.__dict__))
        except Exception as e:
            await websocket.send_text(json.dumps(WsMsg.error(e).__dict__))


@app.websocket("/ws/{cookie_or_token}")
async def websocket_endpoint(*,
                             websocket: WebSocket,
                             # item_id: str,
                             # q: int | None = None,
                             cookie_or_token):
    # cookie_or_token: Annotated[str, Depends(get_cookie_or_token)],
    await manager.connect(cookie_or_token, websocket)
    await main(websocket)


async def main(websocket: WebSocket):
    t1 = asyncio.create_task(recv(websocket))
    # t2 = asyncio.create_task(mock_send_msg(websocket))
    await asyncio.gather(t1)


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
